import * as Sequelize from 'sequelize';
import { DataTypes, Model, Optional } from 'sequelize';

export interface WeixinUserAttributes {
  id: string;
  openid: string;
  unionid?: string;
  nickname?: string;
  avatarUrl?: string;
  gender?: number;
  country?: string;
  province?: string;
  city?: string;
  language?: string;
  sessionKey?: string;
  accessToken?: string;
  refreshToken?: string;
  expiresIn?: number;
  phone?: string;
  status: number;
  lastLoginTime?: Date;
  loginCount: number;
  deviceInfo?: object;
  extraInfo?: object;
  remark?: string;
  createdTime: Date;
  updatedTime: Date;
}

export type WeixinUserPk = 'id';
export type WeixinUserId = WeixinUser[WeixinUserPk];
export type WeixinUserOptionalAttributes =
  | 'unionid'
  | 'nickname'
  | 'avatarUrl'
  | 'gender'
  | 'country'
  | 'province'
  | 'city'
  | 'language'
  | 'sessionKey'
  | 'accessToken'
  | 'refreshToken'
  | 'expiresIn'
  | 'phone'
  | 'status'
  | 'lastLoginTime'
  | 'loginCount'
  | 'deviceInfo'
  | 'extraInfo'
  | 'remark'
  | 'createdTime'
  | 'updatedTime';
export type WeixinUserCreationAttributes = Optional<
  WeixinUserAttributes,
  WeixinUserOptionalAttributes
>;

export class WeixinUser
  extends Model<WeixinUserAttributes, WeixinUserCreationAttributes>
  implements WeixinUserAttributes
{
  id!: string;
  openid!: string;
  unionid?: string;
  nickname?: string;
  avatarUrl?: string;
  gender?: number;
  country?: string;
  province?: string;
  city?: string;
  language?: string;
  sessionKey?: string;
  accessToken?: string;
  refreshToken?: string;
  expiresIn?: number;
  phone?: string;
  status!: number;
  lastLoginTime?: Date;
  loginCount!: number;
  deviceInfo?: object;
  extraInfo?: object;
  remark?: string;
  createdTime!: Date;
  updatedTime!: Date;

  static initModel(sequelize: Sequelize.Sequelize): typeof WeixinUser {
    return WeixinUser.init(
      {
        id: {
          type: DataTypes.CHAR(36),
          allowNull: false,
          primaryKey: true,
          comment: '主键UUID',
        },
        openid: {
          type: DataTypes.STRING(128),
          allowNull: false,
          comment: '微信用户唯一标识',
          unique: 'uk_openid',
        },
        unionid: {
          type: DataTypes.STRING(128),
          allowNull: true,
          comment: '微信开放平台统一标识',
        },
        nickname: {
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: '用户昵称',
        },
        avatarUrl: {
          type: DataTypes.STRING(512),
          allowNull: true,
          comment: '头像URL地址',
          field: 'avatar_url',
        },
        gender: {
          type: DataTypes.TINYINT,
          allowNull: true,
          defaultValue: 0,
          comment: '性别：0-未知，1-男，2-女',
        },
        country: {
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: '国家',
        },
        province: {
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: '省份',
        },
        city: {
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: '城市',
        },
        language: {
          type: DataTypes.STRING(50),
          allowNull: true,
          defaultValue: 'zh_CN',
          comment: '语言',
        },
        sessionKey: {
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: '会话密钥（建议加密存储）',
          field: 'session_key',
        },
        accessToken: {
          type: DataTypes.STRING(512),
          allowNull: true,
          comment: '网页授权接口调用凭证',
          field: 'access_token',
        },
        refreshToken: {
          type: DataTypes.STRING(512),
          allowNull: true,
          comment: '用户刷新access_token',
          field: 'refresh_token',
        },
        expiresIn: {
          type: DataTypes.INTEGER,
          allowNull: true,
          comment: 'access_token接口调用凭证超时时间，单位（秒）',
          field: 'expires_in',
        },
        phone: {
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: '手机号码',
        },
        status: {
          type: DataTypes.TINYINT,
          allowNull: false,
          defaultValue: 1,
          comment: '用户状态：0-禁用，1-正常',
        },
        lastLoginTime: {
          type: DataTypes.DATE,
          allowNull: true,
          comment: '最后登录时间',
          field: 'last_login_time',
        },
        loginCount: {
          type: DataTypes.INTEGER,
          allowNull: false,
          defaultValue: 0,
          comment: '登录次数',
          field: 'login_count',
        },
        deviceInfo: {
          type: DataTypes.JSON,
          allowNull: true,
          comment: '设备信息',
          field: 'device_info',
        },
        extraInfo: {
          type: DataTypes.JSON,
          allowNull: true,
          comment: '扩展信息字段',
          field: 'extra_info',
        },
        remark: {
          type: DataTypes.TEXT,
          allowNull: true,
          comment: '备注信息',
        },
        createdTime: {
          type: DataTypes.DATE,
          allowNull: false,
          defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
          comment: '创建时间',
          field: 'created_time',
        },
        updatedTime: {
          type: DataTypes.DATE,
          allowNull: false,
          defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
          comment: '更新时间',
          field: 'updated_time',
        },
      },
      {
        sequelize,
        tableName: 'weixin_user',
        timestamps: false,
        indexes: [
          {
            name: 'PRIMARY',
            unique: true,
            using: 'BTREE',
            fields: [{ name: 'id' }],
          },
          {
            name: 'uk_openid',
            unique: true,
            using: 'BTREE',
            fields: [{ name: 'openid' }],
          },
          {
            name: 'idx_unionid',
            using: 'BTREE',
            fields: [{ name: 'unionid' }],
          },
          {
            name: 'idx_status',
            using: 'BTREE',
            fields: [{ name: 'status' }],
          },
          {
            name: 'idx_created_time',
            using: 'BTREE',
            fields: [{ name: 'created_time' }],
          },
          {
            name: 'idx_last_login',
            using: 'BTREE',
            fields: [{ name: 'last_login_time' }],
          },
        ],
      },
    );
  }
}
